/**
 * @作者 faner
 * @创建时间 2021/2/23 14:52
 */
package com.faner.fast.activiti;

import com.faner.fast.activiti.model.Evection;
import com.faner.fast.annotation.AnonymousAccess;
import com.faner.fast.constant.enums.CodeEnum;
import com.faner.fast.constant.enums.DictTypeEnum;
import com.faner.fast.util.EnumUtils;
import com.faner.fast.util.R;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.activiti.engine.*;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricProcessInstanceQuery;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.repository.ProcessDefinitionQuery;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@Validated
@RestController
@RequiredArgsConstructor
@Api(value = "activi", tags = "activi模块")
public class ActiviController {

    @AnonymousAccess
    @ApiOperation("流程部署")
    @ApiOperationSupport(order = 10,author = "faner")
    @RequestMapping(value = "/activi/info",method= {RequestMethod.GET})
    public R initSelectParams(){
        //1.创建ProcessEngine
        final ProcessEngine defaultProcessEngine = ProcessEngines.getDefaultProcessEngine();
        final RepositoryService repositoryService = defaultProcessEngine.getRepositoryService();
        final Deployment deploy = repositoryService.createDeployment()
                .name("group-1")
                .addClasspathResource("bpmn/6.bpmn")
//                .addClasspathResource("bpmn/3.png")
                .deploy();
        Map<Object, Object> map = new HashMap<>();
        map.put("id",deploy.getId());
        map.put("name",deploy.getName());
        return  R.ok(map);
    }

    @AnonymousAccess
    @ApiOperation("启动流程设置流程变量")
    @ApiOperationSupport(order = 20,author = "faner")
    @RequestMapping(value = "/activi/testStart",method= {RequestMethod.GET})
    public R testStart(){
        //1.创建ProcessEngine
        final ProcessEngine defaultProcessEngine = ProcessEngines.getDefaultProcessEngine();
        final RuntimeService runtimeService = defaultProcessEngine.getRuntimeService();

        String key = "myEvection2";
        final Evection evection = new Evection();
        evection.setNum(2d);



        Map<Object, Object> map = new HashMap<>();
        map.put("evection",evection);
//        map.put("assignee0",deploy.getName());
//        runtimeService.startProcessInstanceByKey();
        return  R.ok(map);
    }


    @AnonymousAccess
    @ApiOperation("启动流程实例")
    @ApiOperationSupport(order = 30,author = "faner")
    @RequestMapping(value = "/activi/start",method= {RequestMethod.GET})
    public R start(@RequestParam  String key){
        //表act_re_procdef
        final ProcessEngine defaultProcessEngine = ProcessEngines.getDefaultProcessEngine();
        //2.获取RuntimeService
        final RuntimeService runtimeService = defaultProcessEngine.getRuntimeService();
        //3.或许流程定义的id启动流程
        final ProcessInstance myEvection = runtimeService.startProcessInstanceByKey(key);
        Map<Object, Object> map = new HashMap<>();
        map.put("流程定义id",myEvection.getProcessDefinitionId());
        map.put("流程实例id",myEvection.getId());
        map.put("当前活动id",myEvection.getActivityId());
        return  R.ok(map);
    }


    @AnonymousAccess
    @ApiOperation("查询个人待执行的任务")
    @ApiOperationSupport(order = 30,author = "faner")
    @RequestMapping(value = "/activi/find",method= {RequestMethod.GET})
    public R find(){
        final ProcessEngine defaultProcessEngine = ProcessEngines.getDefaultProcessEngine();
        //2.获取TaskService
        final TaskService taskService = defaultProcessEngine.getTaskService();
        //3.根据流程key与负责人查询
        final List<Task> list = taskService.createTaskQuery()
                .processDefinitionKey("myEvection")
                .taskAssignee("zhangsan")
                .list();
        final List<Object> collect = list.stream().map(t -> {
            Map<Object, Object> map = new HashMap<>();
            map.put("流程实例id", t.getProcessInstanceId());
            map.put("任务id", t.getId());
            map.put("任务负责人id", t.getAssignee());
            map.put("任务名称", t.getName());
        return map;
        }).collect(Collectors.toList());
        return  R.ok(collect);
    }
    @AnonymousAccess
    @ApiOperation("完成个人任务")
    @ApiOperationSupport(order = 40,author = "faner")
    @RequestMapping(value = "/activi/completask",method= {RequestMethod.GET})
    public R completask(){
        final ProcessEngine defaultProcessEngine = ProcessEngines.getDefaultProcessEngine();
        //2.获取TaskService
        final TaskService taskService = defaultProcessEngine.getTaskService();
        //3.

        //3.根据流程key与负责人查询
        Task list = taskService.createTaskQuery()
                .processDefinitionKey("group-1")
                .taskAssignee("张三")
                .singleResult();
        taskService.complete(list.getId());
        return  R.ok();
    }


    @AnonymousAccess
    @ApiOperation("查询流程定义")
    @RequestMapping(value = "/activi/queryProcess",method= {RequestMethod.GET})
    public R queryProcess(){
        final ProcessEngine defaultProcessEngine = ProcessEngines.getDefaultProcessEngine();
        //2.获取RepositoryService
        final RepositoryService repositoryService = defaultProcessEngine.getRepositoryService();
        //3.
        final ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();
        //3.根据所有流程 倒叙
        final List<ProcessDefinition> myEvection = processDefinitionQuery.processDefinitionKey("myEvection")
                .orderByProcessDefinitionVersion()
                .desc()
                .list();
        final List<Object> collect = myEvection.stream().map(t -> {
            Map<Object, Object> map = new HashMap<>();
            map.put("流程部署id", t.getDeploymentId());
            map.put("流程定义key", t.getKey());
            return map;
        }).collect(Collectors.toList());
        return  R.ok();
    }

    @AnonymousAccess
    @ApiOperation("流程定义删除")
    @RequestMapping(value = "/activi/delProcess",method= {RequestMethod.GET})
    public R delProcess(){
        //删除表act_ge_bytearray act_re_deployment act_re_procdef
        //不会删除历史信息 因为会用来查询
        final ProcessEngine defaultProcessEngine = ProcessEngines.getDefaultProcessEngine();
        //2.获取RepositoryService
        final RepositoryService repositoryService = defaultProcessEngine.getRepositoryService();
        //3 当前流程未跑完 删除回报错 通过部署id
        repositoryService.deleteDeployment("068cb3ac-75a5-11eb-88f8-6807157c728e");
        //3 强制删除 通过部署id
        repositoryService.deleteDeployment("068cb3ac-75a5-11eb-88f8-6807157c728e",true);
        return  R.ok();
    }

    @AnonymousAccess
    @ApiOperation("流程资源下载")
    @RequestMapping(value = "/activi/download",method= {RequestMethod.GET})
    public R download(){
        //表act_re_procdef
        final ProcessEngine defaultProcessEngine = ProcessEngines.getDefaultProcessEngine();
        //2.获取RepositoryService
        final RepositoryService repositoryService = defaultProcessEngine.getRepositoryService();
        //3.获取查询对象
        final ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();
        ProcessDefinition processDefinition = processDefinitionQuery.processDefinitionKey("myEvection").singleResult();
        //4.获取部署id
        final String deploymentId = processDefinition.getDeploymentId();
        //5 获取png图片流
        final String pngName = processDefinition.getDiagramResourceName();
        final InputStream pngStream = repositoryService.getResourceAsStream(deploymentId, pngName);
        //5.2 获取bpmn的流
        final String bpmnName = processDefinition.getResourceName();
        final InputStream bpmnStream = repositoryService.getResourceAsStream(deploymentId, bpmnName);
        //6.构造outputStream

        return  R.ok();
    }

    @AnonymousAccess
    @ApiOperation("查看历史消息")
    @RequestMapping(value = "/activi/his",method= {RequestMethod.GET})
    public R his(){
        //表act_re_procdef
        final ProcessEngine defaultProcessEngine = ProcessEngines.getDefaultProcessEngine();
        //2.获取HistoryService
        final HistoryService historyService = defaultProcessEngine.getHistoryService();
        final HistoricProcessInstanceQuery instanceQuery = historyService.createHistoricProcessInstanceQuery();
        //查询act_inst表
        instanceQuery.processInstanceId("");
        instanceQuery.orderByProcessInstanceStartTime().asc();
        //查询所有
        final List<HistoricProcessInstance> list = instanceQuery.list();
        return  R.ok();
    }
}
